package com.syncomponents.support.handle;

import javax.annotation.Resource;

import org.perf4j.aop.Profiled;
import org.springframework.util.Assert;

import com.sunkey.log.audit.annotation.Audit;
import com.syncomponents.context.annotation.SynHandler;
import com.syncomponents.context.support.HandlerType;
import com.syncomponents.context.support.MessageHandler;
import com.syncomponents.convert.IMessageConvert;
import com.syncomponents.convert.IMessageConvertContainer;
import com.syncomponents.core.MessageConstant;
import com.syncomponents.remoting.ClientFactory;
import com.syncomponents.remoting.IClient;
import com.syncomponents.remoting.IMessage;
import com.syncomponents.support.ITarget;

import commonj.sdo.DataObject;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.helper.XMLHelper;

/**
 * 消息处理类
 * 
 * @author sunkey
 * @date Jan 13, 2014
 */
@SynHandler(value = "xmlMessageHandler", type = HandlerType.XML)
public class XMLMessageHandler implements MessageHandler {

    @Resource
    private IMessageConvertContainer messageConvertContainer;

    @Resource
    private ClientFactory clientFactory;

    public XMLMessageHandler() {
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.fpx.ce.syn.core.support.handle.IMessageHandler#handle(java.lang.String)
     */
    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Audit(action = "handle")
    @Profiled(tag = "handle({$0})", logger = "com.fpx.ce.syn.core.support.handle.XMLMessageHandler")
    public Object handle(String msg) {

        Assert.notNull(msg, "message can not be null");

        XMLDocument xmlDoc = XMLHelper.INSTANCE.load(msg);

        DataObject dobj = xmlDoc.getRootObject();

        String msgType = dobj.getString(MessageConstant.MESSAGE_TYPE);
        String action = dobj.getString(MessageConstant.MESSAGE_ACTION);

        Assert.notNull(msgType, "msgType is required");
        Assert.notNull(action, "action is required");

        IMessageConvert messageConvert = messageConvertContainer.getMessageConverter(msgType);

        Assert.notNull(messageConvert, "Not supported msgType: " + msgType.toUpperCase());

        IMessage messageRequest = messageConvert.convertReq(dobj, msg);

        ITarget target = messageConvert.getTarget();

        Assert.notNull(target.getClientType(), "ClientType can not be null");

        IClient client = clientFactory.getBean(target.getClientType());

        Assert.notNull(client, "Not supported msgType: " + target.getClientType());

        Object response = client.excute(messageRequest);

        Object result = messageConvert.convertResp(dobj, response);

        return result;
    }

}
